package com.dpac.core.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;


/**
 * @title zip文件压缩工具类
 * @description 请填写相关描述
 * @creator lils
 * @date 2017年5月31日 下午4:27:32
 */
public class ZipUtils {
	
	/**
	 * ZIP压缩
	 * @param sourceDir:压缩源文件的路径,如：c:/20090723/
	 * @param zipFile:压缩后的文件路径,如：c:/20090723.zip
	 * @param isErgodic:是否遍历
	 * @return true of false
	 */
	public static boolean zip(String sourceDir, String zipFile, boolean isErgodic) {
		boolean mark = false;
		try {
			OutputStream os = new FileOutputStream(zipFile);
			BufferedOutputStream bos = new BufferedOutputStream(os);
			ZipOutputStream zos = new ZipOutputStream(bos);
			File file = new File(sourceDir);
			String basePath = null;
			if (file.isDirectory()) {
				basePath = file.getPath();
			} else {
				basePath = file.getParent();
			}
			mark = zipFile(file, basePath, zos, isErgodic);
			zos.closeEntry();
			zos.close();
			os.close();
			bos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		// 压缩zip文件失败，就将zip文件删除
		if (!mark) {
			boolean isDel = deleteFile(zipFile);
			if (!isDel) {
				deleteFile(zipFile);
			}
		}
		return mark;
	}
	
	/**
	 * 压缩文件
	 * @param source:文件源
	 * @param basePath:路径
	 * @param zos:zip输出流
	 * @param isErgodic:是否遍历
	 * @return true of false
	 */
	private static boolean zipFile(File source, String basePath, ZipOutputStream zos, boolean isErgodic) {
		boolean mark = false;
		File[] files = new File[0];
		if (source.isDirectory()) {
			files = source.listFiles();
		} else {
			files = new File[1];
			files[0] = source;
		}
		String pathName;
		byte[] buf = new byte[1024];
		int length = 0;
		try {
			for (File file : files) {
				System.out.println("压缩文件：" + file.getName());
				if (file.isDirectory() && isErgodic) {
					pathName = file.getPath().substring(basePath.length() + 1) + "/";
					zos.putNextEntry(new ZipEntry(pathName));
					zipFile(file, basePath, zos, isErgodic);
				} else if (!file.isDirectory()) {
					pathName = file.getPath().substring(basePath.length() + 1);
					InputStream is = new FileInputStream(file);
					BufferedInputStream bis = new BufferedInputStream(is);
					zos.putNextEntry(new ZipEntry(pathName));
					while ((length = bis.read(buf)) > 0) {
						zos.write(buf, 0, length);
					}
					is.close();
				}
				// throw new Exception("测试异常情况！");
			}
			mark = true;
		} catch (Exception e) {
			e.printStackTrace();
			mark = false;
		}
		return mark;
	}
	
	/**
	 * 解压ZIP文件
	 * @param zipfile:zip文件路径
	 * @param destDir:解压路径
	 * @return true of false
	 */
	public static boolean unZip(String zipfile, String destDir) {
		boolean mark = false;
		try {
			String newDestDir = destDir.replace("\\", "/");
			newDestDir = newDestDir.endsWith("/") ? newDestDir : newDestDir + "/";
			byte b[] = new byte[1024];
			int length;
			ZipFile zipFile = new ZipFile(new File(zipfile));
			Enumeration<?> enumeration = zipFile.entries();
			ZipEntry zipEntry = null;
			while (enumeration.hasMoreElements()) {
				zipEntry = (ZipEntry) enumeration.nextElement();
				String sFileName = zipEntry.getName();
				System.out.println("解压文件：" + sFileName);
				File loadFile = new File(newDestDir + sFileName);
				if (zipEntry.isDirectory()) {
					loadFile.mkdirs();
				} else {
					if (!loadFile.getParentFile().exists()) {
						loadFile.getParentFile().mkdirs();
					}
					OutputStream outputStream = new FileOutputStream(loadFile);
					InputStream inputStream = zipFile.getInputStream(zipEntry);
					while ((length = inputStream.read(b)) > 0) {
						outputStream.write(b, 0, length);
					}
					outputStream.flush();
					inputStream.close();
					outputStream.close();
				}
			}
			zipEntry = null;
			enumeration = null;
			zipFile.close();
			mark = true;
			System.out.println("文件解压成功！");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return mark;
	}
	
	/**
	 * 删除文件
	 * @param filePathAndName:文件路径及名称 如c:/fqf.txt
	 * @param fileContent
	 * @return boolean
	 */
	private static boolean deleteFile(String filePathAndName) {
		boolean mark = false;
		try {
			String filePath = filePathAndName;
			filePath = filePath.toString();
			File myDelFile = new File(filePath);
			if (myDelFile.exists()) {
				myDelFile.delete();
			}
			mark = true;
		} catch (Exception e) {
			System.out.println("删除文件操作出错");
			e.printStackTrace();
		}
		return mark;
	}
	
	public static void main(String[] args) {
		System.out.println("============开始压缩============");
		boolean mark = ZipUtils.zip("d:/测试", "d:/测试.zip", false);
		System.out.println("压缩结果=" + mark);
		System.out.println("============完成压缩============");
		System.out.println();
		System.out.println("============开始解压============");
		boolean mark2 = ZipUtils.unZip("d:/测试.zip", "d:\\测试测试\\/");
		System.out.println("解压结果=" + mark2);
		System.out.println("============完成解压============");
	}
}